package com.zillion.common.utils.http;

import com.zillion.common.constant.Constants;
import com.zillion.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;

import javax.net.ssl.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;

/**
 * HTTPS 请求工具类（忽略证书验证，适用于测试环境）
 */
public class HttpsUtils {

    private static final Logger log = LoggerFactory.getLogger(HttpsUtils.class);

    /**
     * 向指定 URL 发送GET方法的请求（HTTPS）
     *
     * @param url 发送请求的 URL
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String url) {
        return sendGet(url, StringUtils.EMPTY);
    }

    /**
     * 向指定 URL 发送GET方法的请求（HTTPS）
     *
     * @param url 发送请求的 URL
     * @param param 请求参数，格式为 name1=value1&name2=value2
     * @return 响应结果
     */
    public static String sendGet(String url, String param) {
        StringBuilder result = new StringBuilder();
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            log.info("sendGet - {}", urlNameString);

            // 初始化 SSLContext
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());

            URL realUrl = new URL(urlNameString);
            HttpsURLConnection conn = (HttpsURLConnection) realUrl.openConnection();

            // 设置 SSL 相关属性
            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());

            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
            conn.connect();

            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), Constants.UTF8));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            log.info("recv - {}", result);
        } catch (Exception e) {
            log.error("调用HttpsUtils.sendGet Exception, url=" + url + ",param=" + param, e);
        } finally {
            closeQuietly(in);
        }
        return result.toString();
    }

    /**
     * 向指定 URL 发送POST方法的请求（HTTPS）
     *
     * @param url 发送请求的 URL
     * @param param 请求参数，格式为 name1=value1&name2=value2
     * @return 响应结果
     */
    public static String sendPost(String url, String param) {
        return sendPost(url, param, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
    }

    /**
     * 向指定 URL 发送POST方法的请求（HTTPS）
     *
     * @param url 发送请求的 URL
     * @param param 请求参数
     * @param contentType 内容类型（如 application/json 或 application/x-www-form-urlencoded）
     * @return 响应结果
     */
    public static String sendPost(String url, String param, String contentType) {
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try {
            log.info("sendPost - {}", url);

            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());

            URL realUrl = new URL(url);
            HttpsURLConnection conn = (HttpsURLConnection) realUrl.openConnection();

            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());

            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("Content-Type", contentType);

            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.connect();

            out = new PrintWriter(conn.getOutputStream());
            out.print(param);
            out.flush();

            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            log.info("recv - {}", result);
        } catch (Exception e) {
            log.error("调用HttpsUtils.sendPost Exception, url=" + url + ",param=" + param, e);
        } finally {
            try {
                if (out != null) out.close();
                closeQuietly(in);
            } catch (Exception ignored) {}
        }
        return result.toString();
    }

    private static void closeQuietly(AutoCloseable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (Exception ignored) {}
        }
    }

    /**
     * 信任所有证书的 TrustManager
     */
    private static class TrustAnyTrustManager implements X509TrustManager {
        public void checkClientTrusted(X509Certificate[] chain, String authType) {}

        public void checkServerTrusted(X509Certificate[] chain, String authType) {}

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }

    /**
     * 信任所有主机名的 HostnameVerifier
     */
    private static class TrustAnyHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
}
